package yuhuibear.poat.object.pipe;

import java.util.List;

/**
 * 对对象进行查、插、删、改的操作接口。
 * 
 * @author yuhui_bear
 */
public interface ObjectAccessPipe {

	/**
	 * 按照条件列出 type 对应的表中的所有对象。
	 * 
	 * @param <T>
	 * @param type
	 * @param conditions
	 * @param params
	 * @return
	 * @throws java.lang.Exception
	 */
	public <T> List<T> list(Class<T> type, String[] conditions,
			Object... params) throws Exception;

	/**
	 * 按照条件取得单个 type 对应的表中的所有对象。 如果结果多余一个，则会被载断.
	 * 
	 * @param <T>
	 * @param type
	 * @param conditions
	 * @param params
	 * @return
	 * @throws java.lang.Exception
	 */
	public <T> T get(Class<T> type, String[] conditions, Object... params)
			throws Exception;

	/**
	 * 按照条件取得单个 type 对应的表中的所有对象。 如果结果多余一个，则会被载断. <BR>
	 * 用于多表合并查询， 并提取其中几个列。需要的列于 as 条件中描述。<br>
	 * 例如：select table_a.atb1 as name , func(table_b.atb1) as dscp<br>
	 * 则对应的 as ： TableA.Atb1 as name<br>
	 * func(TableB.Atb1) as dscp<br>
	 * 对象的属性名也可以由Field标签指定.
	 * <p>
	 * 例子：<br>
	 * //需要使用多表查询组装的对象。<br>
	 * Class type = UserLog.class;<br>
	 * //as 后面的名称必须和 UserLog 中的属性的映射后的名称相同。 String[] as = new String[]{"Log.id as id", "User.name as who_name",
	 * "Log.dsp as comment", "Log.time AS time"};<br>
	 * String[] conditions = new String[]{"Log.time > '2008-11-10'", "Log.ownerId = User.id"};<br>
	 * //查询中没有参数， 所以可以省略参数。<br>
	 * List<UserLog> result = pm.getPipe().list(as, type, conditions);<br>
	 * </p>
	 * 
	 * @param <T>
	 * @param as
	 * @param type
	 * @param conditions
	 * @param params
	 * @return
	 * @throws java.lang.Exception
	 */
	public <T> List<T> list(String[] as, Class<T> type, String[] conditions,
			Object... params) throws Exception;

	/**
	 * 用于多表合并查询， 并提取其中几个列。需要的列于 as 条件中描述。<br>
	 * 例如：select table_a.atb1 as name , func(table_b.atb1) as dscp<br>
	 * 则对应的 as ： TableA.Atb1 as name<br>
	 * func(TableB.Atb1) as dscp<br>
	 * 对象的属性名也可以由Field标签指定.
	 * <p>
	 * 例子：<br>
	 * //需要使用多表查询组装的对象。<br>
	 * Class type = UserLog.class;<br>
	 * //as 后面的名称必须和 UserLog 中的属性的映射后的名称相同。 String[] as = new String[]{"Log.id as id", "User.name as who_name",
	 * "Log.dsp as comment", "Log.time AS time"};<br>
	 * String[] conditions = new String[]{"Log.time > '2008-11-10'", "Log.ownerId = User.id"};<br>
	 * //查询中没有参数， 所以可以省略参数。<br>
	 * List<UserLog> result = pm.getPipe().list(as, type, conditions);<br>
	 * </p>
	 * 
	 * @param <T>
	 * @param expression
	 * @param type
	 * @param conditions
	 * @param params
	 * @return
	 * @throws java.lang.Exception
	 */
	public <T> T get(String expression, Class<T> type, String[] conditions,
			Object... params) throws Exception;

	/**
	 * 将对象保存到数据库中。<br>
	 * 如果对象的某个属性有标签：AutoGenerateValue，则当这个属性为 null 且 .skipOnNull = true 时, 在对象被保存到数据库之后，标签对应的值会被填入数据库刚刚产生的值。
	 * 
	 * @param <T>
	 * @param obj
	 * @throws java.lang.Exception
	 */
	public <T> void add(T obj) throws Exception;

	/**
	 * 将对象保存到数据库中。<br>
	 * 如果对象的某个属性有标签：AutoGenerateValue，则当这个属性为 null 且 .skipOnNull = true 时, 在对象被保存到数据库之后，标签对应的值会被填入数据库刚刚产生的值。
	 * 
	 * @param <T>
	 * @param objs
	 * @return
	 * @throws java.lang.Exception
	 */
	public <T> int add(List<T> objs) throws Exception;

	/**
	 * 更新对象.<BR>
	 * 这个方法是void update(T oldone, T newone) 的替代版。 <h1>
	 * 这个方法只根据 primary key 来定位对象。</h1>
	 * 
	 * @param <T>
	 * @param obj
	 * @throws Exception
	 */
	public <T> void update(T obj) throws Exception;

	/**
	 * 按照conditions 条件，更新 type 对应的关系表中的所有满足条件的对象。<br>
	 * 对象的所有值都将被用 attrs 中的值替换。attrs 的写法：new String[]{"Log.dsp  =  ?", "Log.id = id + 10000000"}
	 * 
	 * @param type
	 * @param attrs
	 * @param conditions
	 *            如果要更新所有记录条件为 new String[]{"*"} , 而不是 null.
	 * @param params
	 * @return 影响的记录条数。
	 * @throws java.lang.Exception
	 */
	public int update(Class<?> type, String[] attrs, String[] conditions,
			Object... params) throws Exception;

	/**
	 * 删除对象。
	 * 
	 * @param <T>
	 * @param obj
	 * @throws java.lang.Exception
	 */
	public <T> void delete(T obj) throws Exception;

	/**
	 * 删除所有 objs 中的对象。影响的记录条数。
	 * 
	 * @param <T>
	 * @param objs
	 * @return
	 * @throws java.lang.Exception
	 */
	public <T> int delete(List<T> objs) throws Exception;

	/**
	 * 按照条件删除对象。
	 * 
	 * @param <T>
	 * @param type
	 * @param conditions
	 *            如果要删除所有记录条件为 new String[]{"*"} , 而不是 null.
	 * @param params
	 * @return 影响的记录条数。
	 * @throws java.lang.Exception
	 */
	public <T> int delete(Class<T> type, String[] conditions, Object... params)
			throws Exception;

	// /**
	// * 开始事务。自动事务管理方式会被取代掉。
	// * @throws Exception
	// */
	// public void start() throws Exception;

	/**
	 * 提交之前的事务。<br>
	 * 
	 * @throws Exception
	 */
	public void commit() throws Exception;

	/**
	 * 回滚到上次提交后的状态。
	 * 
	 * @throws java.lang.Exception
	 */
	public void rollback() throws Exception;

	// /**
	// * 撤销当前事务的所有操作。<br>
	// * 同时会清除掉之前的所有的保存点
	// * @throws java.lang.Exception
	// */
	// public void rollbackAll() throws Exception;

	// /**
	// * 设置保存点。
	// * 所有的保存点是按照堆栈方式组织的。
	// * @throws java.lang.Exception
	// */
	// public void setSavePoint() throws Exception;

	/**
	 * 设置页长度。 <hl>只对下次查询生效。</hl>
	 * 
	 * @param len
	 */
	public void setPageLenth(Integer len);

	/**
	 * 设置页码。 <hl>只对下次查询生效。</hl>
	 * 
	 * @param page
	 */
	public void setPageNumber(Integer page);

	/**
	 * 是否加入 对 order by 的字段 加入distinct.
	 * <p>
	 * 默认: ture.
	 * </p>
	 * 
	 * @param distinct
	 */
	public void setDistinct(boolean distinct);

	/**
	 * 关闭管道, 但是不会提交事务， 所有尚未提交的事务的都会丢失。之后这个管道将不能做任何操作。
	 * 
	 * @throws java.lang.Exception
	 */
	public void close() throws Exception;
}
